﻿#include "multi_list_widget.h"
#include "ui_multi_list_widget.h"
#include <QStandardItemModel>
#include <QCheckBox>
#include <QApplication>
#include <QPainter>
#include <QMouseEvent>

CmbBoxItemDelegate::CmbBoxItemDelegate(QObject *parent) : QStyledItemDelegate(parent)
{

}

QWidget* CmbBoxItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    return QStyledItemDelegate::createEditor(parent, option, index);
}

void CmbBoxItemDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const
{
    if (option->state.testFlag(QStyle::State_HasFocus))
    {
        //option->backgroundBrush = m_backColor.value<QColor>();
    }
}

QSize CmbBoxItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    return QStyledItemDelegate::sizeHint(option, index);
}

void CmbBoxItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyleOptionViewItem viewOption(option);
    initStyleOption(&viewOption, index);
    QStyleOptionButton btnOption;
    btnOption.rect = option.rect;
    btnOption.rect.setLeft(option.rect.left() + 23);
    btnOption.rect.setTop(option.rect.top() + 7);
    btnOption.rect.setWidth(14);
    btnOption.rect.setHeight(14);
    btnOption.state = index.data(Qt::UserRole + 1).value<bool>() ? QStyle::State_On : QStyle::State_Off;
    btnOption.state |= QStyle::State_Enabled;

    QCheckBox btn;
    btn.setCheckable(true);
    btn.setChecked(index.data(Qt::UserRole + 1).toBool());

    QApplication::style()->unpolish(&btn);
    QApplication::style()->polish(&btn);
    QApplication::style()->drawControl(QStyle::CE_CheckBox, &btnOption, painter, &btn);

    QFont font;
    font.setPixelSize(16);
    QFontMetrics metrics(font);
    painter->setFont(font);

    painter->drawText(QPoint(option.rect.left() + 64, option.rect.top() + 19), index.data(Qt::DisplayRole).value<QString>());

    QStyledItemDelegate::paint(painter, option, index);
}

bool CmbBoxItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    if (event->type() == QEvent::MouseButtonDblClick)
    {
        return true;
    }
    if (event->type() == QEvent::MouseButtonRelease)
    {
        return false;
    }

    QApplication::restoreOverrideCursor();

    if (event->type() == QEvent::MouseButtonPress)
    {
        emit signal_btn_clicked(index);
    }

    return QStyledItemDelegate::editorEvent(event, model, option, index);
}

void CmbBoxItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
{
    editor->setGeometry(option.rect);
}

MultiListWidget::MultiListWidget(QWidget *parent) : QWidget(parent), ui(new Ui::MultiListWidget)
{
	ui->setupUi(this);
	initPage();
}

MultiListWidget::~MultiListWidget()
{
	delete ui;
}

void MultiListWidget::initPage()
{
	m_pModel = new QStandardItemModel();
    auto *delegate = new CmbBoxItemDelegate(this);
	ui->listView->setItemDelegate(delegate);
    ui->listView->setModel(m_pModel);

    connect(delegate, &CmbBoxItemDelegate::signal_btn_clicked, this, [this](const QModelIndex& index)
	{
        QStringList texts = m_text.isEmpty() ? QStringList() : m_text.split(";");

        bool checked = !index.data(Qt::UserRole + 1).toBool();
        m_pModel->setData(index, checked, Qt::UserRole + 1);

        if (checked)
        {
            texts.append(index.data(Qt::DisplayRole).toString());
        }
        else
        {
            texts.removeOne(index.data(Qt::DisplayRole).toString());
        }
        m_text = texts.join(";");

        emit signal_text(m_text);
	});
}

void MultiListWidget::addItem(const QString& text, const QVariant& userData)
{
    QStandardItem *pItem = new QStandardItem;
    pItem->setData(false, Qt::UserRole + 1);
    pItem->setData(text, Qt::DisplayRole);
    pItem->setData(userData, Qt::UserRole);
    m_pModel->appendRow(pItem);
}

void MultiListWidget::setData(const QVariant& data)
{
    QStringList texts;
    auto datas = data.toList();
    for (int index = 0; index < m_pModel->rowCount(); ++index)
    {
        auto mIndex = m_pModel->index(index, 0);
        if (datas.contains(mIndex.data(Qt::UserRole)))
        {
            m_pModel->setData(mIndex, true, Qt::UserRole + 1);
            texts.append(mIndex.data().toString());
        }
    }
    m_text = texts.join(";");

    emit signal_text(m_text);
}

QVariant MultiListWidget::data() const
{
    QVariantList datas;
    for (int index = 0; index < m_pModel->rowCount(); ++index)
    {
        auto mIndex = m_pModel->index(index, 0);
        if (mIndex.data(Qt::UserRole + 1).toBool())
        {
            datas.append(mIndex.data(Qt::UserRole));
        }
    }
    return datas;

}
